package models

import (
	"errors"
	"fmt"
	"reflect"
	"strings"
	"time"
     "strconv"
	"github.com/astaxie/beego/orm"
	"library/common"
)


type ToaUser struct {
	Id           int       `orm:"column(id);auto"`
	Username     string    `orm:"column(username);size(40);null"`
	Password     string    `orm:"column(password);size(40);null"`
	Pswdhash     string    `orm:"column(pswdhash);size(128);null"`
	Departmentid string    `orm:"column(departmentid);size(50);null"`
	Department   string    `orm:"column(department);size(100);null"`
	Company      string    `orm:"column(company);size(10)"`
	Flag         string    `orm:"column(flag);size(2);null"`
	Date         time.Time `orm:"column(date);type(datetime);null"`
	Ischeck      string    `orm:"column(ischeck);size(2);null"`
	Userkey      string    `orm:"column(userkey);size(50);null"`
	Groupid      string    `orm:"column(groupid);size(2);null"`
	Positionid   string    `orm:"column(positionid);size(20);null"`
	Loginip      string    `orm:"column(loginip);null"`
	Online       string    `orm:"column(online);size(2);null"`
	Keytype      string    `orm:"column(keytype);size(2);null"`
	Keytypeuser  string    `orm:"column(keytypeuser);null"`
	Numbers      int       `orm:"column(numbers);null"`
	Empno        string    `orm:"column(empno);size(20);null"`
	OpenId       string    `orm:"column(open_id);size(255);null"`
	Realname     string    `orm:"column(realname);size(40);null"`
	Rtx          string    `orm:"column(rtx);size(32);null"`
	Email        string    `orm:"column(email);size(128);null"`
	Phone        string    `orm:"column(phone);size(60);null"`
	Tel          string    `orm:"column(tel);size(50);null"`
	WechatStatus string    `orm:"column(wechat_status);size(1);null"`
	PswdUpd      int8      `orm:"column(pswd_upd);null"`
	Roleid       int       `orm:"column(roleid);null"`
	Updatetime   time.Time `orm:"column(updatetime);type(timestamp);null"`
	Stationid    int       `orm:"column(stationid);null"`
	DirectLeader int       `orm:"column(direct_leader);null"`
}

type UserInfo struct {
	Id   		     int         `json:"id"`
	Username 	     string      `json:"username"`
    Email            string      `json:"email"`
	Rtx 	         string    	 `json:"rtx"`
    Company          string      `json:"company"`
	Positionid 	     string      `json:"positionid"`
    Departmentid     string      `json:"departmentid"`
	Phone       	 string      `json:"phone"`
    Empno            string      `json:"empno"`
	Realname         string      `json:"realname"`
	PositionName     string      `json:"positionName"`
    DepartmentName   string      `json:"departmentName"`
}

func (t *ToaUser) TableName() string {
	return "toa_user"
}

func init() {
	orm.RegisterModel(new(ToaUser))
}

// AddToaUser insert a new ToaUser into database and returns
// last inserted Id on success.
func AddToaUser(m *ToaUser) (id int64, err error) {
	o := orm.NewOrm()
	id, err = o.Insert(m)
	return
}

// GetToaUserById retrieves ToaUser by Id. Returns error if
// Id doesn't exist
func GetToaUserById(id int) (v *ToaUser, err error) {
	o := orm.NewOrm()
	v = &ToaUser{Id: id}
	if err = o.Read(v); err == nil {
		return v, nil
	}
	return nil, err
}

// GetToaUserById retrieves ToaUser by Id. Returns error if
// Id doesn't exist
func GetToaUserByName(username string) (userinfo  UserInfo, msg string) {
	o := orm.NewOrm()
	o.Using("toa")
	userinfo = UserInfo{}
	var userInfomation []orm.Params
	num, err := o.Raw("SELECT * FROM toa_user WHERE username=?", username).Values(&userInfomation)
	if err ==nil{
	if num == 0  {
		msg = "不存在此用户"
		fmt.Println("Find user failed")
		return userinfo, msg
	}else{
		   //获取职位名称
		   positionid:=common.GetInt(userInfomation[0]["positionid"])
		    position := &ToaPosition{ Id:positionid}
 			if err = o.Read(position); err == nil {
				userinfo.PositionName = position.Name		
				 }else{
					 userinfo.PositionName=""
				 }
            
	 		//  获取部门全称
            departmentArr := strings.Split(common.GetString(userInfomation[0]["departmentid"]), ",")
			departmentId := departmentArr[len(departmentArr)-1]
			departmentIdInt,err:=strconv.Atoi(departmentId)
			department := &ToaDepartment{Id:departmentIdInt}
			if err = o.Read(department); err == nil {
				userinfo.DepartmentName = department.GetFullName()		
			}else{
				userinfo.DepartmentName = ""
			}

			userinfo.Id = common.GetInt(userInfomation[0]["id"])
			userinfo.Username = common.GetString(userInfomation[0]["username"])
			userinfo.Email = common.GetString(userInfomation[0]["email"])
			userinfo.Rtx = common.GetString(userInfomation[0]["rtx"])
			userinfo.Company = common.GetString(userInfomation[0]["company"])
			userinfo.Positionid = common.GetString(userInfomation[0]["positionid"])
			userinfo.Departmentid = common.GetString(userInfomation[0]["departmentid"])
			userinfo.Phone = common.GetString(userInfomation[0]["phone"])
			userinfo.Empno = common.GetString(userInfomation[0]["empno"])
			userinfo.Realname = common.GetString(userInfomation[0]["realname"])
		return userinfo, ""
	}
  }
  return 
}

// GetAllToaUser retrieves all ToaUser matches certain condition. Returns empty list if
// no records exist
func GetAllToaUser(query map[string]string, fields []string, sortby []string, order []string,
	offset int64, limit int64) (ml []interface{}, err error) {
	o := orm.NewOrm()
	qs := o.QueryTable(new(ToaUser))
	// query k=v
	for k, v := range query {
		// rewrite dot-notation to Object__Attribute
		k = strings.Replace(k, ".", "__", -1)
		if strings.Contains(k, "isnull") {
			qs = qs.Filter(k, (v == "true" || v == "1"))
		} else {
			qs = qs.Filter(k, v)
		}
	}
	// order by:
	var sortFields []string
	if len(sortby) != 0 {
		if len(sortby) == len(order) {
			// 1) for each sort field, there is an associated order
			for i, v := range sortby {
				orderby := ""
				if order[i] == "desc" {
					orderby = "-" + v
				} else if order[i] == "asc" {
					orderby = v
				} else {
					return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
				}
				sortFields = append(sortFields, orderby)
			}
			qs = qs.OrderBy(sortFields...)
		} else if len(sortby) != len(order) && len(order) == 1 {
			// 2) there is exactly one order, all the sorted fields will be sorted by this order
			for _, v := range sortby {
				orderby := ""
				if order[0] == "desc" {
					orderby = "-" + v
				} else if order[0] == "asc" {
					orderby = v
				} else {
					return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
				}
				sortFields = append(sortFields, orderby)
			}
		} else if len(sortby) != len(order) && len(order) != 1 {
			return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
		}
	} else {
		if len(order) != 0 {
			return nil, errors.New("Error: unused 'order' fields")
		}
	}

	var l []ToaUser
	qs = qs.OrderBy(sortFields...)
	if _, err = qs.Limit(limit, offset).All(&l, fields...); err == nil {
		if len(fields) == 0 {
			for _, v := range l {
				ml = append(ml, v)
			}
		} else {
			// trim unused fields
			for _, v := range l {
				m := make(map[string]interface{})
				val := reflect.ValueOf(v)
				for _, fname := range fields {
					m[fname] = val.FieldByName(fname).Interface()
				}
				ml = append(ml, m)
			}
		}
		return ml, nil
	}
	return nil, err
}

// UpdateToaUser updates ToaUser by Id and returns error if
// the record to be updated doesn't exist
func UpdateToaUserById(m *ToaUser) (err error) {
	o := orm.NewOrm()
	v := ToaUser{Id: m.Id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Update(m); err == nil {
			fmt.Println("Number of records updated in database:", num)
		}
	}
	return
}

// DeleteToaUser deletes ToaUser by Id and returns error if
// the record to be deleted doesn't exist
func DeleteToaUser(id int) (err error) {
	o := orm.NewOrm()
	v := ToaUser{Id: id}
	// ascertain id exists in the database
	if err = o.Read(&v); err == nil {
		var num int64
		if num, err = o.Delete(&ToaUser{Id: id}); err == nil {
			fmt.Println("Number of records deleted in database:", num)
		}
	}
	return

}
/**
 * 获取部门完整名称
 */
func (d *ToaDepartment) GetFullName() string {
	if d.Father == "0" {
		return d.Name
	}
	return d.GetParentName() + "-" + d.Name
}

/**
 * 获取部门的上级部门名称
 */
func (d *ToaDepartment) GetParentName() string {
	if father, err := strconv.Atoi(d.Father); err == nil && father > 0 {
		o := orm.NewOrm()
		o.Using("toa")
		fatherDepartment := &ToaDepartment{Id:father}
	    if err = o.Read(fatherDepartment); err == nil {
					if fatherFather, err := strconv.Atoi(fatherDepartment.Father); err == nil && fatherFather > 0 {
				return fatherDepartment.GetParentName() + "-" + fatherDepartment.Name
			}
			return fatherDepartment.Name
			}
	}
	return ""
}

